﻿using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace WLCompiler.Helpers.SemanticAnalyze
{
    public class ReferenceContainer<T> : IEnumerable<T> where T : UniqueObject
    {
        protected readonly IList<T> Elements = new List<T>();

        public ReferenceContainer() {}

        public ReferenceContainer(IEnumerable<T> elements)
            : this()
        {
            foreach (var element in elements)
            {
                Elements.Add(element);
            }
        }

        public T Resolve(string id)
        {
            return Elements.FirstOrDefault(element => element.Id == id);
        }

        public T Resolve(T uniqueObject)
        {
            return Elements.FirstOrDefault(element => element == uniqueObject);
        }

        public void Add(T uniqueObject)
        {
            Elements.Add(uniqueObject);
        }

        public void Remove(T uniqueObject)
        {
            var removedElement = Elements.FirstOrDefault(element => element == uniqueObject);
            if (removedElement == null)
            {
                return;
            }

            Elements.Remove(removedElement);
        }

        public void Remove(string id)
        {
            var removedElement = Elements.FirstOrDefault(element => element.Id == id);
            if (removedElement == null)
            {
                return;
            }

            Elements.Remove(removedElement);
        }

        public bool Contains(string id)
        {
            return Elements.Any(element => element.Id == id);
        }

        public static ReferenceContainer<T> operator +(ReferenceContainer<T> first, ReferenceContainer<T> second)
        {
            return new ReferenceContainer<T>(first.Concat(second));
        }

        #region Implementation of IEnumerable

        public IEnumerator<T> GetEnumerator()
        {
            return Elements.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}
